#!/bin/bash

echo "
---------------------------------------------------------------
               __                                              
   ____  ___  / /______        _________  ____  ____ ___  _____
  / __ \/ _ \/ //_/ __ \      / ___/ __ \/ __ \/ __ '__ \/ ___/
 / / / /  __/ ,< / /_/ /_____/ /  / /_/ / /_/ / / / / / (__  ) 
/_/ /_/\___/_/|_|\____/_____/_/   \____/\____/_/ /_/ /_/____/  
                                                               
                 Automatic installer by m1k1o                  
---------------------------------------------------------------

You need to have:

 - OS:
   - Kernel version 2 or higher.
   - Debian 9 or higher.
   - Ubuntu 18.04 or higher.

 - Hardware:
   - Memory at least 2GB.
   - CPU at least 4 cores.
   - Disk at least 8GB.

 - Network:
   - Public IP.
   - Free TCP ports 80 and 443.
   - Free UDP port range (59000-59100).
   - Domain name pointing to your IP.

 - Run this script as superuser.
"

while true; do
  read -rp "Are you ready to continue? [Y/n] " yn
  case $yn in
    "") break ;;
    [Yy]*) break ;;
    [Nn]*) exit 0 ;;
    *) echo "Please answer yes or no." ;;
  esac
done

# Detect Debian users running the script with "sh" instead of bash
if readlink /proc/"$$"/exe | grep -q "dash"; then
  echo 'This installer needs to be run with "bash", not "sh".' >&2
  exit 1
fi

# Detect Root
if [[ "${EUID}" -ne 0 ]]; then
  echo "This installer needs to be run with superuser privileges." >&2
  exit 1
fi

# Detect OS
if grep -qs "ubuntu" /etc/os-release; then
  OS_VERSION="$(grep 'VERSION_ID' /etc/os-release | cut -d '"' -f 2 | tr -d '.')"

  if [[ "${OS_VERSION}" -lt 1804 ]]; then
    echo "Ubuntu 18.04 or higher is required to use this installer." >&2
    echo "This version of Ubuntu is too old and unsupported." >&2
    exit 1
  fi
elif [[ -e /etc/debian_version ]]; then
  OS_VERSION="$(grep -oE '[0-9]+' /etc/debian_version | head -1)"

  if [[ "${OS_VERSION}" -lt 9 ]]; then
    echo "Debian 9 or higher is required to use this installer." >&2
    echo "This version of Debian is too old and unsupported." >&2
    exit 1
  fi
else
  echo "This installer seems to be running on an unsupported distribution." >&2
  echo "Supported distributions are Ubuntu and Debian." >&2
  exit 1
fi

# Detect Kernel
if [[ "$(uname -r | cut -d "." -f 1)" -eq 2 ]]; then
  echo "The system is running an old kernel, which is incompatible with this installer." >&2
  exit 1
fi

#
# Install docker
#

if ! dockerd --help > /dev/null 2>&1; then
  while true; do
    read -rp "Docker is not installed. Do you wish to install this program? [Y/n]" yn
    case $yn in
      [Yy]*) break ;;
      [Nn]*) exit 0 ;;
      *) echo "Please answer yes or no." ;;
    esac
  done

  apt-get remove containerd docker docker-engine docker.io runc
  apt-get update
  apt-get install -y \
    apt-transport-https \
    ca-certificates \
    curl \
    gnupg \
    lsb-release

  curl -fsSL https://download.docker.com/linux/ubuntu/gpg | gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg

  echo \
    "deb [arch=amd64 signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu \
        $(lsb_release -cs) stable" | tee /etc/apt/sources.list.d/docker.list > /dev/null

  apt-get update
  apt-get install -y containerd.io docker-ce docker-ce-cli docker-buildx-plugin docker-compose-plugin
fi

echo "[Y] Docker is installed..."

#
# Install dependencies
#

apt-get update
apt-get install -y apache2-utils sed

echo "[Y] Dependencies are installed..."

#
# Prompt for data
#

# Epr
read -rp "Enter UDP port range: (default 59000-59100) " NEKO_ROOMS_EPR
if [[ -z "${NEKO_ROOMS_EPR}" ]]; then
  NEKO_ROOMS_EPR="59000-59100"
fi

# Domain
while true; do
  read -rp "Enter your domain name: (e.g. example.com) " NEKO_ROOMS_TRAEFIK_DOMAIN
  if [[ -z "${NEKO_ROOMS_TRAEFIK_DOMAIN}" ]]; then
    echo "Please enter your domain."
    continue
  fi

  break
done

# Timezone
TZ_DEF="$(cat /etc/timezone)"
read -rp "Current timezone: (default ${TZ_DEF}) " TZ
if [[ -z "${TZ}" ]]; then
  TZ="${TZ_DEF}"
fi

# Email
while true; do
  read -rp "Enter your email for Let's Encrypt domain notification: " TRAEFIK_EMAIL
  if [[ -z "${TRAEFIK_EMAIL}" ]]; then
    echo "Please enter your email. Or, well, use fake if you want..."
    continue
  fi

  break
done

touch "./usersfile"

# Users
while true; do
  echo "Add new user:"

  # Username
  read -rp " | - Username: (default admin) " USR_NAME
  if [[ -z "${USR_NAME}" ]]; then
    USR_NAME="admin"
  fi

  # Password
  read -rp " | - Password: (default admin) " -s USR_PASS
  if [[ -z "${USR_PASS}" ]]; then
    USR_PASS="admin"
  fi

  htpasswd -nb "${USR_NAME}" "${USR_PASS}" >> usersfile

  echo
  read -rp "Do you want to add another user? [y/N] " yn
  case $yn in
    "") break ;;
    [Yy]*) echo ;;
    [Nn]*) break ;;
    *) echo "Please answer yes or no." ;;
  esac
done

echo "[Y] Got all settings..."

#
# Create env
#

NEKO_IMAGES=(m1k1o/neko:firefox m1k1o/neko:chromium m1k1o/neko:google-chrome)

{
  echo "TZ=${TZ}"
  echo "NEKO_ROOMS_EPR=${NEKO_ROOMS_EPR}"
  echo "NEKO_ROOMS_TRAEFIK_DOMAIN=${NEKO_ROOMS_TRAEFIK_DOMAIN}"
  echo "NEKO_ROOMS_TRAEFIK_ENTRYPOINT=websecure"
  echo "NEKO_ROOMS_TRAEFIK_NETWORK=neko-rooms-traefik"
  echo "NEKO_ROOMS_TRAEFIK_CERTRESOLVER=lets-encrypt"
  echo "NEKO_ROOMS_NEKO_IMAGES=${NEKO_IMAGES[*]}"
} > .env

echo "[Y] Creating env..."

#
# Download traefik config
#

mkdir -p "./config"

wget -O "./traefik.yml" "https://raw.githubusercontent.com/m1k1o/neko-rooms/master/traefik/traefik.yml"
sed -i "s/yourname@example.com/${TRAEFIK_EMAIL}/g" "./traefik.yml"

wget -O "./config/middlewares.yml" "https://raw.githubusercontent.com/m1k1o/neko-rooms/master/traefik/config/middlewares.yml"
wget -O "./config/routers.yml" "https://raw.githubusercontent.com/m1k1o/neko-rooms/master/traefik/config/routers.yml"
wget -O "./config/tls.yml" "https://raw.githubusercontent.com/m1k1o/neko-rooms/master/traefik/config/tls.yml"

touch "./acme.json"
chmod 600 "./acme.json"

echo "[Y] Downloading traefik config..."

#
# Download docker compose file
#

wget -O "./docker-compose.yml" "https://raw.githubusercontent.com/m1k1o/neko-rooms/master/traefik/docker-compose.yml"

# Pull neko images
for NEKO_IMAGE in "${NEKO_IMAGES[@]}"; do
  docker pull "${NEKO_IMAGE}"
done

# docker-compose was renamed to docker compose, support both
if docker-compose --version > /dev/null 2>&1; then
  docker-compose pull
  docker-compose up -d
else
  docker compose pull
  docker compose up -d
fi

echo "[Y] Finished! You can now visit https://${NEKO_ROOMS_TRAEFIK_DOMAIN}/"
